package com.fan.cachewebview.pool

import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.view.ViewGroup
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import com.fan.cachewebview.core.CacheOpenApi
import com.fan.cachewebview.core.CacheConfig
import com.fan.cachewebview.core.CacheMode
import com.fan.cachewebview.core.interceptor.ResourceInterceptor

/**
 * @description $
 * @date: 2022/2/16 10:54
 * @author: fan
 */
open class CacheWebView : WebView, CacheOpenApi {

    var mCacheClient: CacheWebViewClient? = null
    var mUserWebViewClient: WebViewClient? = null
    var mRecycled: Boolean = false


    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(
        context, attrs
    )

    constructor(
        context: Context, attrs: AttributeSet?,
        defStyleAttr: Int
    ) : super(context, attrs, defStyleAttr)

    override fun setWebViewClient(client: WebViewClient) {
        if (mCacheClient != null) {
            mCacheClient!!.updateProxyClient(client)
        } else {
            super.setWebViewClient(client)
        }
        mUserWebViewClient = client
    }


    override fun addResourceInterceptor(interceptor: ResourceInterceptor) {
        if (mCacheClient != null) {
            mCacheClient!!.addResourceInterceptor(interceptor)
        }
    }

    override fun destroy() {
        release()
        super.destroy()
    }

    open fun release() {
        stopLoading()
//        loadUrl("")
        setRecycled(true)
        webChromeClient = null
        var settings = settings
        settings.javaScriptEnabled = false
        settings.blockNetworkImage = false
        clearHistory()
        clearCache(true)
        removeAllViews()
        var viewParent = parent
        if (viewParent != null && viewParent is ViewGroup) {
            viewParent.removeView(this)
        }
        if (mCacheClient != null) {
            mCacheClient!!.destroy()
        }
    }

    /**
     * 预加载页面
     */
    fun preload(context: Context, url: String?) {
        if (!TextUtils.isEmpty(url)) {
            setCacheMode(CacheMode.CACHE)
            loadUrl(url!!)
        }
    }


    fun setCacheMode(mode: CacheMode) {
        setCacheMode(mode, null)
    }


    override fun setCacheMode(mode: CacheMode, config: CacheConfig?) {
        if (mode == CacheMode.NO_CACHE) {
            mCacheClient = null;
            if (mUserWebViewClient != null) {
                webViewClient = mUserWebViewClient!!
            }
        } else {
            mCacheClient = CacheWebViewClient(this)
            if (mUserWebViewClient != null) {
                mCacheClient!!.updateProxyClient(mUserWebViewClient!!)
            }
            mCacheClient!!.setCacheMode(mode, config)
            super.setWebViewClient(mCacheClient!!)
        }
    }


    fun runJs(function: String?, vararg args: Any?) {
        val script = StringBuilder("javascript:")
        script.append(function).append("(")
        if (args.isNotEmpty()) {
            for (i in args.indices) {
                var arg = args[i] ?: continue
                if (arg is String) {
                    arg = "'$arg'"
                }
                script.append(arg)
                if (i != args.size - 1) {
                    script.append(",")
                }
            }
        }
        script.append(");")
        runJs(script.toString())
    }

    override fun getWebViewClient(): WebViewClient {
        return if (mUserWebViewClient != null) mUserWebViewClient!! else super.getWebViewClient()
    }

    override fun canGoBack(): Boolean {
        return !mRecycled && super.canGoBack()
    }

    private fun runJs(script: String) {
        this.loadUrl(script)
    }


    fun isRecycled(): Boolean {
        return mRecycled
    }

    fun setRecycled(recycled: Boolean) {
        mRecycled = recycled
    }

}